#ifndef  ATTACK_HPP
# define ATTACK_HPP

# include <Shinygami/Applejack/body.hpp>
# include <Shinygami/observatory.hpp>

class Attack
{
public:
    struct Effect
    {
	enum EffectType
	{
	    STUN,
	    RESISTANCE_MALUS,
	    SPEED_MALUS
	};

	Effect(EffectType type, float duration, float value) : type(type), duration(duration), value(value)
	{}

	EffectType  type;
	float       value;
	float       duration;
	sf::Clock   timer;
    };

    typedef std::list<Effect> Effects;

    struct Target
    {
	typedef Observatory::Signal<int, const Effects&> Signal;

	Target(Shiny::Applejack::Fixture* fixture) : fixture(fixture), collision(false) {}

	Signal                     Hit;
	Shiny::Applejack::Fixture* fixture;
	bool                       collision;
    };

    Attack(bool& canLaid, Shiny::Applejack::Fixture* fixture);

    void SetFixture(Shiny::Applejack::Fixture* fixture);
    void UnsetFixture(Shiny::Applejack::Fixture* = 0);

    void SetCollision(b2Contact* contact, bool value);
    void BeginCollision(b2Contact* contact)
    {
	SetCollision(contact, true);
    }

    void EndCollision(b2Contact* contact)
    {
	SetCollision(contact, false);
    }

    void operator()(void);

    static void Functor(Attack* attack)
    {
	(*attack)();
    }

    std::list<Target> targets;
    Effects           effects;
    int               damage;

private:
    Shiny::Applejack::Fixture* fixture;
    bool&                      canLaid;
    Observatory::ObserverId    contactBegin, contactEnd, fixtureDestroyed;
};


#endif
